package com.ingenico.insider.services.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.logging.Logger;

import javax.swing.Action;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

import com.ingenico.insider.swing.AboutAction;
import com.ingenico.insider.util.Constants;

public final class HelpSupplier {
	private static final Logger _logger = Logger.getLogger(HelpSupplier.class.getCanonicalName()); 

	/**
	 * Public constant keywords
	 */
	public static final String HELP_KEY = "help";
	public static final String SEPARATOR = Constants.SEPARATOR;
	public static final String HELP_ABOUT_KEY = HELP_KEY + SEPARATOR + "about";
	
	/**
	 * singleton instance
	 */
	private static HelpSupplier instance;

	private final Action aboutAction;

	private void initMenu() {
		final JMenu helpMenu = StandardMenuSupplier.getInstance().getHelpMenu();
		final Action[] actions = new Action[] {
			aboutAction
		};

		JMenuItem currentMenuItem;

		// Loop to init all file menu items at once and register them with a single action handler
		if (helpMenu.getItemCount() > 0) {
			helpMenu.addSeparator();
		}
		for (int i = 0; i < actions.length; i++) {
			currentMenuItem = new JMenuItem();
			currentMenuItem.setAction(actions[i]);
			helpMenu.add(currentMenuItem);
		}
	}
	
	/**
	 * private constructor of final class to prevent external instantiation
	 */
	private HelpSupplier() {
		// Create actions
		aboutAction  = LocalisationSupplier.getInstance().localize(new AboutAction(), HELP_ABOUT_KEY);

		/* 
		 * Get the bundle's manifest file using the bundle class loader,
		 * then extract build id information that has been stored there
		 * by the maven packager... or do nothing if the info cannot be
		 * fetched.
		 */
		try {
			final Manifest mf;
			final InputStream in;
			final Attributes attrs;

			in = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
			if (in != null) {
				String buildId = null;

				mf = new Manifest(in);
				attrs = mf.getMainAttributes();
				if (attrs != null) {
					buildId = attrs.getValue(Constants.BUILD_ID);
				} else {
					_logger.info("Manifest does not contain main attributes. The manifest file may be invalid");
				}

				final StringBuilder sb = new StringBuilder();
				sb.append(aboutAction.getValue(Action.LONG_DESCRIPTION));

				if (buildId != null) {
					sb.append(" - Build-ID: ");
					sb.append(buildId);
				} else {
					sb.append(" - Development Snapshot");					
				}
				aboutAction.putValue (Action.LONG_DESCRIPTION, sb.toString());
				in.close();
			}
		} catch (IOException e) {
			_logger.info("Could not read manifest information. The manifest file may be invalid");
		}

		// Prepare the menu
		initMenu();
	}

	/**
	 * retrieve the singleton instance
	 *
	 * @return the HelpSupplier singleton
	 */
	public static HelpSupplier getInstance() {
		if (instance == null) {
			_logger.info(HelpSupplier.class.getName() + " instance does not exist... Creating instance.");
			instance = new HelpSupplier();
		}
		return instance;
	}
}
